#ifndef _FLASH_SITE_H_
#define _FLASH_SITE_H_

#include <exdispid.h>
#include <ocmm.h>

#include <atlcom.h>
#include "IOleTimer.h"

class FlashView;

class FlashSite :
	public IOleContainer,
	public IOleInPlaceSiteWindowless,
	public IOleClientSite,
	public IServiceProvider,
	public ITimerService
{
public:
	FlashSite(FlashView * view) :
		m_ref(0),
		m_owner(NULL),
		m_bTimerService(FALSE)
	{
		m_owner = view;
	}	

	virtual ~FlashSite()
	{
	}

	HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppv)
	{
		*ppv = 0;
		if(riid == IID_IUnknown)
		{
			*ppv = (IUnknown*)(IOleWindow*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleWindow)
		{
			*ppv = (IOleWindow*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleInPlaceSite)
		{
			*ppv = (IOleInPlaceSite*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleInPlaceSiteEx)
		{
			*ppv = (IOleInPlaceSiteEx*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleInPlaceSiteWindowless)
		{
			*ppv = (IOleInPlaceSiteWindowless*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleClientSite)
		{
			*ppv = (IOleClientSite*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IOleContainer)
		{
			*ppv = (IOleContainer*)this;
			AddRef();
			return S_OK;
		}
		else if (riid == IID_IServiceProvider)
		{
			*ppv = (IServiceProvider*)this;
			AddRef();
			return S_OK;
		}
		else
		{
			return E_NOTIMPL;
		}
	}

	ULONG STDMETHODCALLTYPE AddRef()
	{
		return ++m_ref;
	}

	ULONG STDMETHODCALLTYPE Release()
	{
		m_ref--;
		int tmp = m_ref;
		if(m_ref == 0)
		{
			delete this;
		}
		return tmp;
	}

	HRESULT STDMETHODCALLTYPE ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
	{
		return E_NOTIMPL;
	}

	HRESULT STDMETHODCALLTYPE EnumObjects(DWORD dwFlags, IEnumUnknown **ppenum)
	{
		return E_NOTIMPL;
	}

	HRESULT STDMETHODCALLTYPE LockContainer(BOOL bLock)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE SaveObject(void)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk)
	{
		*ppmk = NULL;
		return E_NOTIMPL;
	}

	HRESULT STDMETHODCALLTYPE GetContainer(IOleContainer **ppContainer)
	{
		return QueryInterface(IID_IOleContainer, (void**)ppContainer);
	}

	HRESULT  STDMETHODCALLTYPE ShowObject(void)
	{
		return S_OK;
	}

	HRESULT  STDMETHODCALLTYPE OnShowWindow(BOOL)
	{
		return S_OK;
	}

	HRESULT  STDMETHODCALLTYPE RequestNewObjectLayout(void)
	{
		return E_UNEXPECTED;
	}

	HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE GetWindow(HWND __RPC_FAR* theWnndow)
	{
		return E_FAIL;
	}

	HRESULT STDMETHODCALLTYPE CanInPlaceActivate(void)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE OnInPlaceActivate(void)
	{		
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE OnUIActivate(void)
	{		
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE GetWindowContext(IOleInPlaceFrame __RPC_FAR *__RPC_FAR *ppFrame, IOleInPlaceUIWindow __RPC_FAR *__RPC_FAR *ppDoc, 
		LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo);

	HRESULT STDMETHODCALLTYPE Scroll(SIZE scrollExtant)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL fUndoable)
	{		
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate(void)
	{	
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE DiscardUndoState(void)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE DeactivateAndUndo(void)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL __RPC_FAR *pfNoRedraw, DWORD dwFlags)
	{		
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL fNoRedraw)
	{		
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE RequestUIActivate(void)
	{
		return S_FALSE;
	}

	HRESULT STDMETHODCALLTYPE CanWindowlessActivate(void)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE GetCapture(void)
	{
		return S_FALSE;
	}

	HRESULT STDMETHODCALLTYPE SetCapture(BOOL fCapture)
	{
		return S_FALSE;
	}

	HRESULT STDMETHODCALLTYPE GetFocus(void)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE SetFocus(BOOL fFocus)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE GetDC(LPCRECT pRect, DWORD grfFlags, HDC __RPC_FAR *phDC)
	{		
		return E_INVALIDARG;
	}

	HRESULT STDMETHODCALLTYPE ReleaseDC(HDC hDC)
	{
		return E_INVALIDARG;
	}

	HRESULT STDMETHODCALLTYPE InvalidateRect(LPCRECT pRect, BOOL fErase);

	HRESULT STDMETHODCALLTYPE InvalidateRgn(HRGN hRGN, BOOL fErase);

	HRESULT STDMETHODCALLTYPE ScrollRect(INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip)
	{
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE AdjustRect(LPRECT prc)
	{
		if(!prc)
			return E_INVALIDARG;
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE OnDefWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT __RPC_FAR *plResult)
	{
		return S_FALSE;
	}

    HRESULT SetTimerService(BOOL bUseTimerService)
    {
        m_bTimerService = bUseTimerService;
        return S_OK;
    }

	HRESULT STDMETHODCALLTYPE CreateTimer(ITimer *pReferenceTimer, ITimer **ppNewTimer)
	{
        if (!m_bTimerService)
        {
            return E_NOTIMPL;
        }

		*ppNewTimer = new CComObjectNoLock<COleTimer>;
		if (*ppNewTimer)
		{
			(*ppNewTimer)->AddRef();
		}
		return S_OK;
	}

	HRESULT STDMETHODCALLTYPE GetNamedTimer(REFGUID rguidName, ITimer **ppTimer)
	{
		return E_NOTIMPL;
	}

	HRESULT STDMETHODCALLTYPE SetNamedTimerReference(REFGUID rguidName, ITimer *pReferenceTimer)
	{
		return E_NOTIMPL;
	}

	HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
	{
        if (!m_bTimerService)
        {
            return E_NOTIMPL;
        }

		if (::IsEqualGUID(__uuidof(ITimerService),riid) )
		{
			(*ppvObject) = (ITimerService*)this;
			AddRef();
			return S_OK;
		}

		return E_NOINTERFACE;
	}
protected:
	int	m_ref;
	FlashView* m_owner;
	BOOL m_bTimerService;
};

#endif